package com.nutiteq.kmlzzz;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.midlet.MIDletStateChangeException;

import com.nutiteq.MapComponent;
import com.nutiteq.components.KmlPlace;
import com.nutiteq.components.OnMapElement;
import com.nutiteq.components.Place;
import com.nutiteq.components.PlaceInfo;
import com.nutiteq.components.WgsPoint;
import com.nutiteq.controls.ControlKeys;
import com.nutiteq.kml.KmlService;
import com.nutiteq.listeners.ErrorListener;
import com.nutiteq.listeners.MapListener;
import com.nutiteq.listeners.OnMapElementListener;
import com.nutiteq.maps.CloudMade;
import com.nutiteq.utils.DummyStarter;
import com.nutiteq.utils.InitializedCanvas;
import com.nutiteq.utils.LogForm;

public class KmlCanvas extends Canvas implements CommandListener, MapListener, ErrorListener,
    OnMapElementListener, InitializedCanvas {
  private final MapComponent map;

  private final Command exit = new Command("Exit", Command.EXIT, 0);
  private final Command editServices = new Command("Services", Command.ITEM, 0);
  private final Command listAll = new Command("List all", Command.ITEM, 0);
  private final Command listVisible= new Command("List visible", Command.ITEM, 0);
  private final Command infoOk = new Command("OK", Command.OK, 0);

  private Image splash;

  private final Timer timer;
  private Thread starter;

  public static KmlCanvas instance;
  private boolean initialized;

  public KmlCanvas() {
    instance = this;
    try {
      splash = Image.createImage("/splash.png");
    } catch (final IOException e) {
      e.printStackTrace();
    }

    timer = new Timer();
    timer.schedule(new TimerTask() {
      public void run() {
        starter = new Thread(new DummyStarter(ShowKml.instance, instance));
        starter.start();
      }
    }, 3000);
    map = new MapComponent("abcdtrial", ShowKml.instance, getWidth(), getHeight(), new WgsPoint(
        26.718200, 58.375230), 7);
  }

  public void initialize() {
    map.startMapping();
    if (hasPointerEvents()) {
      map.showDefaultOnScreenZoomControls();
    } else {
      map.showDefaultCursor();
    }
    map.defineControlKey(ControlKeys.MOVE_UP_KEY, -1);
    map.defineControlKey(ControlKeys.MOVE_DOWN_KEY, -2);
    map.defineControlKey(ControlKeys.MOVE_LEFT_KEY, -3);
    map.defineControlKey(ControlKeys.MOVE_RIGHT_KEY, -4);
    map.defineControlKey(ControlKeys.SELECT_KEY, -5);
    //MPowerPlayer
    map.defineControlKey(ControlKeys.MOVE_UP_KEY, 38);
    map.defineControlKey(ControlKeys.MOVE_DOWN_KEY, 40);
    map.defineControlKey(ControlKeys.MOVE_LEFT_KEY, 37);
    map.defineControlKey(ControlKeys.MOVE_RIGHT_KEY, 39);
    map.defineControlKey(ControlKeys.SELECT_KEY, 10);
    //for motorola
    map.defineControlKey(ControlKeys.MOVE_UP_KEY, KEY_NUM2);
    map.defineControlKey(ControlKeys.MOVE_DOWN_KEY, KEY_NUM8);
    map.defineControlKey(ControlKeys.MOVE_LEFT_KEY, KEY_NUM4);
    map.defineControlKey(ControlKeys.MOVE_RIGHT_KEY, KEY_NUM6);
    map.defineControlKey(ControlKeys.SELECT_KEY, KEY_NUM5);

    map.showZoomLevelIndicator(true);

    map.setMapListener(this);
    map.setErrorListener(this);
    map.setOnMapElementListener(this);

    addCommand(exit);
    addCommand(editServices);
    addCommand(listAll);
    addCommand(listVisible);
    addCommand(LogForm.SHOW_LOG);
    setCommandListener(this);

    initialized = true;

    repaint();
  }

  protected void paint(final Graphics g) {
    if (!initialized) {
      //paint splash
      g.setColor(0xFFFFFFFF);
      g.setClip(0, 0, getWidth(), getHeight());
      g.fillRect(0, 0, getWidth(), getHeight());
      g.drawImage(splash, (getWidth() - splash.getWidth()) / 2,
          (getHeight() - splash.getHeight()) / 2, Graphics.TOP | Graphics.LEFT);
      return;
    }

    map.paint(g);
  }

  public void commandAction(final Command cmd, final Displayable d) {
    if (cmd == exit) {
      map.stopMapping();
      try {
        ShowKml.instance.destroyApp(true);
      } catch (final MIDletStateChangeException ignore) {
      }
    } else if (cmd == editServices) {
        Display.getDisplay(ShowKml.instance).setCurrent(new ServicesList(map, this));
    } else if (cmd == listVisible) {
        Display.getDisplay(ShowKml.instance).setCurrent(new PlacesList(map.getVisiblePlaces()));
    } else if (cmd == listAll) {
    	final KmlService[] services = map.getKmlServices();
    	Vector allPlaces = new Vector();; 
    	for (int i=0;i<services.length;i++){
    	  KmlPlace[] places = map.getKmlPlaces(services[i]);
    	  for (int j=0;j<places.length;j++){
    		  allPlaces.addElement(places[j].getPlace());  
    	  }
    	}
    	Place[] kml = new Place[allPlaces.size()];
    	allPlaces.copyInto(kml);
        Display.getDisplay(ShowKml.instance).setCurrent(new PlacesList(kml));
    } else if (cmd == infoOk) {
      Display.getDisplay(ShowKml.instance).setCurrent(this);
    } else if (cmd == LogForm.SHOW_LOG) {
      Display.getDisplay(ShowKml.instance).setCurrent(new LogForm(map, ShowKml.instance, this));
    }
  }

  public void mapClicked(final WgsPoint p) {

  }

  public void mapMoved() {

  }

  public void needRepaint(final boolean mapIsComplete) {
    repaint();
  }

  protected void keyPressed(final int keyCode) {
    if (!initialized) {
      return;
    }
    map.keyPressed(keyCode);
  }

  protected void keyReleased(final int keyCode) {
    if (!initialized) {
      return;
    }
    map.keyReleased(keyCode);
  }

  protected void keyRepeated(final int keyCode) {
    if (!initialized) {
      return;
    }
    map.keyRepeated(keyCode);
  }

  protected void pointerDragged(final int x, final int y) {
    if (!initialized) {
      return;
    }
    map.pointerDragged(x, y);
  }

  protected void pointerPressed(final int x, final int y) {
    if (!initialized) {
      return;
    }
    map.pointerPressed(x, y);
  }

  protected void pointerReleased(final int x, final int y) {
    if (!initialized) {
      return;
    }
    map.pointerReleased(x, y);
  }

  public void licenseError(final String message) {
    System.out.println("License error: " + message);
  }

  public void networkError(final String message) {
    System.out.println("Network error: " + message);
  }

  public void elementClicked(final OnMapElement element) {
    if (!(element instanceof Place)) {
      return;
    }

    final Place place = (Place) element;
    final PlaceInfo info = map.getAdditionalInfo(place);

    if (info == null) {
      return;
    }

    final Form infoForm = new Form(info.getName());
    infoForm.append("Name: " + info.getName() + "\n");
    infoForm.append("Address: " + info.getAddress() + "\n");
    infoForm.append("Snippet: " + info.getSnippet() + "\n");
    if (info.getCoordinates() != null) {
      infoForm.append("Location: " + info.getCoordinates().getLon() + " "
          + info.getCoordinates().getLat());
    }
    infoForm.append("Description: " + info.getDescription() + "\n");
    infoForm.addCommand(infoOk);
    infoForm.setCommandListener(this);

    Display.getDisplay(ShowKml.instance).setCurrent(infoForm);
  }

  public void elementEntered(final OnMapElement p) {

  }

  public void elementLeft(final OnMapElement p) {

  }
}
